package org.ninekone.testGame;

public class GameCharacter {
	public final static int HUMAN_TYPE=0;
	public final static int ANDROID_TYPE=1;
	public final static int STANDING=0;
	public final static int TO_LEFT=1;
	public final static int TO_FORWARD=2;
	public final static int TO_RIGHT=3;
	public final static int TO_BACKWARD=4;
	public final static float WALK_SPEED=1.0f;
	public final static float RUN_SPEED=5.0f;
	private final static int STRENGHT=15; 
	private int characterType;
	private boolean valid;
	private float currentXPos;
	private float currentZPos;
	private int steps;
	private int runningDirection;

	
	
	
	private GameCharacter(int characterType){
		switch (characterType){
		case 0:
			this.characterType=HUMAN_TYPE;
			valid=true;
			break;
		case 1:
			this.characterType=ANDROID_TYPE;
			valid=true;
			break;
		default:
			valid=false;
		}
		generateCharacter();
	}
	public void generateCharacter(){
		if (characterType==0){
			System.out.println("Personaggio umano");
			//inserire qui le direttive per generare un cubo blu
			//sistema di controllo: pilotato da tastiera
			currentXPos=0.0f;
			currentZPos=0.0f;
			//currentSpeed=WALK_SPEED;
		}
		
		if (characterType==1){
			System.out.println("Personaggio artificiale");
			//inserire qui le direttive per generare un cubo rosso			
			currentXPos=0.0f;
			currentZPos=0.0f;
		}
	}
	/*public GameCharacter[] getCharacters() {
		// TODO Auto-generated method stub
		return null;
	}*/
	public static GameCharacter getGameCharacter(int characterType){
		if (characterType==HUMAN_TYPE || characterType==ANDROID_TYPE){
			GameCharacter GC=new GameCharacter(characterType);
			return GC;
		}else {
			return null;
		}
	}
	
	public float getXPos(){
		return currentXPos;
	}

	public float getZPos(){
		return currentZPos;
	}

	/**metodo per la gestione della corsa,
	 * va richiamato all'interno di un ciclo
	 * per permettere alla corsa di completarsi.
	 * aggiorna le variabili che gestiscono l'avanzamento della corsa.
	 * @param direction	The running direction of the character
	 * @return if the run is possible or not.   
	 * */
	public boolean runfast(int direction){
		boolean canRun=false;
		if (direction >= 1 && direction <= 4){
			if (steps == 0 && runningDirection == STANDING){
				canRun=true;
				runningDirection=direction;
				steps++;
			}else if ((steps > 0 && steps <= STRENGHT) && direction == runningDirection){
				canRun=true;
				steps++;
			}else if (steps > STRENGHT){
				canRun=false;
				steps=0;
				runningDirection = STANDING;
			}else{
				canRun=false;
			}
			if (canRun){
				switch (direction){
				case TO_LEFT:
					currentXPos=currentXPos-RUN_SPEED;
					break;
				case TO_FORWARD:
					currentZPos=currentZPos+RUN_SPEED;
					break;
				case TO_RIGHT:
					currentXPos=currentXPos+RUN_SPEED;
					break;
				case TO_BACKWARD:
					currentZPos=currentZPos-RUN_SPEED;					
				}
			}
		}
		return canRun;
	}
	
	/**metodo per la gestione della camminata,
	 * non può essere eseguito se lo stato è running
	 * @param direction	The running direction of the character
	 * @return if the run is possible or not.   
	 * */
	public boolean walk(int direction){
		boolean canWalk=false;
		if (direction >=1 && direction <=4){
			if (runningDirection == STANDING){
				canWalk=true;
				switch (direction){
				case TO_LEFT:
					currentXPos=currentXPos-WALK_SPEED;
					break;
				case TO_FORWARD:
					currentZPos=currentZPos+WALK_SPEED;
					break;
				case TO_RIGHT:
					currentXPos=currentXPos+WALK_SPEED;
					break;
				case TO_BACKWARD:
					currentZPos=currentZPos-WALK_SPEED;					
				}

			}else{
				canWalk=false;
			}
		}else{
			canWalk=false;
		}
		return canWalk;
	}
	/*
	public boolean setCurrentSpeed(float speed){
		if (speed==WALK_SPEED || speed==RUN_SPEED){
			currentSpeed=speed;
			return true;
		}else{
			return false;
		}
	}
	*/
	//aggiungere dei controlli decenti per gestire la corsa con numero di step limitati
	//ad esempio, quando si cammina è sufficiente eseguire la mossa richiesta, ma quando si corre
	//occorre fare in modo che inizi una sessione di corsa: una volta iniziata la corsa in quella direzione 
	//il mezzo non accetta input da altre direzioni di quella iniziale finchè lo stato è [running][direzione], 
	//mentre il buffer degli step continua a salire fino a raggiungere il valore massimo, dopodichè vengono resettati gli stati, 
	//[running] ridiventa walking
	//[direzione] è annullato
	//gli step vengono azzerati
	//E' possibile interrmpere il processo di corsa premendo il tasto per la cancellazione del comando,
	//anche in questo caso si azzereranno i parametri di corsa come se si fosse raggiunto il numero di step massimi.
	
}